/*************************************************************************************
   This is the constructor function for our new TriStateCheckBox class.
   Calling it creates a TriStateCheckBox object and outputs the required
   <a> and <img> tags into the specified document at the current location. 
   Therefore, don't call it for the current document from an event handler.
   Arguments:
      document: The Document object the buttons are be created in.
      checked:  A boolean that says whether the button is initially checked.
      label:    An optional string that specifies text to appear after the button.
      onclick:  An optional function to be called when the toggle button is
                clicked. It is passed a boolean indicating the new
                state of the button. You can also pass a string, which is
                be converted to a function that is passed a boolean argument
                named "state".
*************************************************************************************/
function TriStateCheckBox( document, checked, label, onclick )
{
  // The first time we are called (and only the first time), we have
  // to do some special stuff. First, now that the prototype object
  // is created, we can set up our methods. 
  // Second, we need to load the images we'll be using.
  // Doing this gets the images in the cache for when we need them.
  if( !TriStateCheckBox.prototype.over )
  {
    // Initialize the prototype object to create our methods.
    TriStateCheckBox.prototype.over   = _TriStateCheckBox_over;
    TriStateCheckBox.prototype.out    = _TriStateCheckBox_out;
    TriStateCheckBox.prototype.click  = _TriStateCheckBox_click;
    TriStateCheckBox.prototype.enable = _TriStateCheckBox_enable;

    // Now create an array of image objects, and assign URLs to them.
    // The URLs of the images are configurable and are stored in an
    // array property of the constructor function itself. They are
    // initialized below. Because of a bug in Netscape, we've got
    // to maintain references to these images, so we store the array
    // in a property of the constructor rather than using a local variable.
    TriStateCheckBox.images = new Array(6);
    for( var i = 0; i < 6; i++ )
    {
      TriStateCheckBox.images[i]     = new Image( TriStateCheckBox.width, TriStateCheckBox.height );
      TriStateCheckBox.images[i].src = TriStateCheckBox.imagenames[i];
    }
  }

  // Save some of the arguments we were passed.
  this.document = document;
  this.checked  = checked;
  this.enabled  = true;

  // Remember that the mouse is not currently on top of us.
  this.highlighted = false;

  // Save the onclick argument to be called when the button is clicked.
  // If it is not already a function, attempt to convert it
  // to a function that is passed a single argument, named state.
  this.onclick = onclick;
  if( typeof this.onclick == "string" )
  {
    this.onclick = new Function("state", this.onclick);
  }

  // Figure out what entry in the document.images[] array the images
  // for this checkbox will be stored at.
  var index = document.images.length;

  // Now output the HTML code for this checkbox. Use <a> and <img> tags.
  // The event handlers we output here are confusing but crucial to the
  // operation of this class. The "_tb" property is defined below, as
  // are the over(), out(), and click() methods.
  document.write('&nbsp;<a href="about:blank" ' +
                 'onmouseover="document.images[' + index + ']._tb.over();return true;" '+
                 'onmouseout="document.images[' + index + ']._tb.out()" '+
                 'onclick="document.images[' + index + ']._tb.click(); return false;">');
  document.write('<img src="' + TriStateCheckBox.imagenames[this.checked+0] +'"'+
                 ' width=' + TriStateCheckBox.width +
                 ' height=' + TriStateCheckBox.height +
                 ' border="0" hspace="0" vspace="0" align="absmiddle">');
  if( label ) document.write(label);
  document.write('</a></br>');

  // Now that we've output the <img> tag, save a reference to the
  // Image object that it created in the TriStateCheckBox object.
  this.image = document.images[index];

  // And also make a link in the other direction, from the Image object
  // to this TriStateCheckBox object. Do this by defining a "_tb" property
  // in the Image object.
  this.image._tb = this;
}

// This becomes the over() method.
function _TriStateCheckBox_over()
{
  if( this.enabled )
  {
    // Change the image, and remember that we're highlighted.
    this.image.src = TriStateCheckBox.imagenames[this.checked + 2];
    this.highlighted = true;
  }
}

// This becomes the out() method.
function _TriStateCheckBox_out()
{
  if( this.enabled )
  {
    // Change the image, and remember that we're not highlighted.
    this.image.src = TriStateCheckBox.imagenames[this.checked + 0];
    this.highlighted = false;
  }
}

// This becomes the click() method.
function _TriStateCheckBox_click()
{
  if( this.enabled )
  {
    // Toggle the state of the button, change the image, and call the
    // onclick method, if it was specified for this TriStateCheckBox.
    this.checked = !this.checked;
    this.image.src = TriStateCheckBox.imagenames[this.checked+this.highlighted*2];
    if( this.onclick ) this.onclick(this.checked);
  }
  else
  {
    this.checked = false;
    this.enabled = true;
    this.image.src = TriStateCheckBox.imagenames[this.checked+this.highlighted*2];
    if( this.onclick ) this.onclick(this.checked);
  }
}

// This becomes the enable() method
function _TriStateCheckBox_enable( enable )
{
  this.enabled = enable;
  if( this.enabled == false )
  {
    this.highlighted = false;
    if( this.checked )
    {
      this.image.src = TriStateCheckBox.imagenames[ 5 ];
    }
    else
    {
      this.image.src = TriStateCheckBox.imagenames[ 4 ];
    }
  }
  else
  {
    if( this.checked )
    {
      this.image.src = TriStateCheckBox.imagenames[ 1 ];
    }
    else
    {
      this.image.src = TriStateCheckBox.imagenames[ 0 ];
    }
  }
}

// Initialize static class properties that describe the checkbox images. These
// are just defaults. Programs can override them by assigning new values.
// But they should only be overridden *before* any ToggleButtons are created.
TriStateCheckBox.imagenames    = new Array(4);            // Create an array.
TriStateCheckBox.imagenames[0] = "/images/button0.gif"; // The unchecked box
TriStateCheckBox.imagenames[1] = "/images/button1.gif"; // The box with a check mark
TriStateCheckBox.imagenames[2] = "/images/button2.gif"; // Unchecked but highlighted
TriStateCheckBox.imagenames[3] = "/images/button3.gif"; // Checked and highlighted
TriStateCheckBox.imagenames[4] = "/images/button4.gif"; // Disabled and unchecked
TriStateCheckBox.imagenames[5] = "/images/button5.gif"; // Disabled and checked
TriStateCheckBox.width         = 25;                      // Size of all images
TriStateCheckBox.height        = 25;     


/*************************************************************************************
                               A debug window class
*************************************************************************************/
function DebugWindow()
{
  //*** Disabled by default
  this.enabled = false;

  //*** The debug window instance
  this.dbgWnd = null;

  //*** Define the methods
  if( !DebugWindow.prototype.Enable )
  {
    DebugWindow.prototype.Enable = _debugEnable;
    DebugWindow.prototype.Start  = _debugStart;
    DebugWindow.prototype.Stop   = _debugStop;
    DebugWindow.prototype.w      = _debugWrite;
  }
}

function _debugEnable( enable )
{
  this.enabled = enable;
  if( enable )
  {
    if( this.dbgWnd == null )
    {
      this.dbgWnd = window.open();
    }
  }
  else
  {
    if( this.dbgWnd != null )
    {
      this.dbgWnd.close();
    }
  }
}

function _debugStart()
{
  if( this.enabled )
  {
    this.dbgWnd.document.open();
    this.dbgWnd.document.write( "<HTML><HEAD><TITLE>Debug</TITLE></HEAD><BODY>" );
  }
}

function _debugStop()
{
  if( this.enabled )
  {
    this.dbgWnd.document.write( "</BODY></HTML>" );
    this.dbgWnd.document.close();
  }
}

function _debugWrite( text )
{
  if( this.enabled )
  {
    this.dbgWnd.document.write( text );
  }
}

